// JointRegularSet.cpp: implementation of the JointRegularSet class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "PHSShare.h"
#include "JointRegularSet.h"
#include "JointPart.h"
#include "JointFunction.h"
#include "Part.h"
#include "global.h"
#include "ProductCatalogManager.h"
#include "JointPortFormer.h"
#include "JoinInfo.h"
#include "GeneralJointRegular.h"
#include "Joint.h"
#include "DBConnectionManager.h"
#include "KnownPartSet.h"
#include "PersistentFacade.h"
#include "PartGenerator.h"
#include "ProjectManager.h"
#include "PHSDirectorySetting.h"
#include "PHSApp.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

using namespace JointSystem;
using namespace DAWrapper;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
/*
JointRegularSet theRegularSet;
JointRegularSet& GetJointRegularSet()
{
	return theRegularSet;
}
*/

JointRegularSet::SpecialJointRegularSetGenerator JointRegularSet::m_RegularSetGenerator;
JointRegularSet::SpecialJointRegularSet& JointRegularSet::GetSpecialJointRegularSet()
{
	return *m_RegularSetGenerator.Generate();
}

JointRegularSet::JointRegularSet()
{
	m_strRegularSetTableName = _T("JPFormat_Matching_Rule");
	ASSERT(GetProjectManager().CurProject());
	
	Project* pPrj = GetProjectManager().CurProject();
	m_strDBPath = GetCurDirectorySetting().PrjTemplateDir() + GetPHSApp()->JointFormerName();
	m_bIsRead = FALSE;
}

JointRegularSet::~JointRegularSet()
{
}

BOOL JointRegularSet::IsLegal(INT nFirstStyle, INT nSecondStyle)
{
	if(!m_bIsRead)
		ReadRegular();

	CString strKey;
	strKey.Format(_T("%d_%d"), nFirstStyle, nSecondStyle);

	if(this->GetManaged(strKey) == NULL)
		return FALSE;
	return TRUE;
}

JointRegular* JointRegularSet::GenerateRegular(INT nFirstStyle, INT nSecondStyle)
{
	if(!m_bIsRead)
		ReadRegular();

	JointRegular* pRegular = NULL;
/*	pRegular = new JointRegular;
	if(pRegular == NULL)
	{
		ReportMemoryError();
		return NULL;
	}*/
	return pRegular;
}

const _ConnectionPtr& JointRegularSet::GetRegularSetDB()
{
	CString strDataSource;
	return *DBConnectionManager::Instance()->GetConnectionPtrByUri(m_strDBPath);
}

void JointRegularSet::CloseConnection()
{
}

JointRegular* JointRegularSet::GenerateRegular(JointFunction *pFirst, JointFunction *pNext)
{
	if(!m_bIsRead)
		ReadRegular();

	ASSERT(pFirst);
	ASSERT(pNext);

	JointRegular* pJointRegular = GenerateSpecialRegular(pFirst, pNext);
	if(pJointRegular != NULL)
		return pJointRegular;

	CString strKey;
	strKey.Format(_T("%d_%d"), pFirst->GetJointStyle(), pNext->GetJointStyle());
	GeneralJointRegular* pRegular = this->GetManaged(strKey);
	ASSERT(pRegular);

	pRegular = pRegular->Clone();
	
	pRegular->SetFirstFormer(pFirst->GetFormer());
	pRegular->SetNextFormer(pNext->GetFormer());

	return pRegular;
}


BOOL JointRegularSet::HasJointed(Part &part, JointPortFormer* pFormer)
{
/*	JointInfo info(&part);
	JointFunction* pFunction = NULL;

	pFunction = info.GetFirst();
	while(pFunction != NULL)
	{
		Joint* pJoint = pFunction->GetJoint();
		if(pJoint != NULL)
		{
			if(static_cast<GeneralJointRegular*>(pJoint->m_pRegular)->HasJointPort(pFormer))
				return TRUE;
		}
		pFunction = info.GetNext();
	}
*/
	return FALSE;
}

JointRegular* JointRegularSet::GenerateSpecialRegular(JointFunction *pFirst, JointFunction *pNext)
{
	ASSERT(pFirst);
	ASSERT(pNext);
	DWORD dwKey = 0;

	SpecialJointRegularSet& SpecialJointRegular = GetSpecialJointRegularSet();
	if(pNext->GetJointStyle() == JointFunction::eCONSTSPRINGEXTERNALTHREAD_RH ||
		pNext->GetJointStyle() == JointFunction::eCONSTSPRINGEXTERNALTHREAD_LH ||
		pNext->GetJointStyle() == JointFunction::eCONSTSPRINGINTERNALTHREAD_RH ||
		pNext->GetJointStyle() == JointFunction::eCONSTSPRINGINTERNALTHREAD_LH ||
		pNext->GetJointStyle() == JointFunction::eCONSTSPRINGEYE)
	{
		dwKey = JointFunction::eCONSTSPRINGJOINTPORT;
	}
	else
	{
		INT nFirstStyle = pFirst->GetJointStyle();
		INT nSecondStyle = pNext->GetJointStyle();
		
		dwKey = JointRegular::RegularSerialNumGenerator(nFirstStyle, nSecondStyle);
	}

	return NULL;
/*	SpecialJointRegularInfo* pInfo = SpecialJointRegular.Get(dwKey);
	if(pInfo == NULL)
	{
		return NULL;
	}
	return pInfo->CreateObject();*/
}


void JointRegularSet::ReadRegular()
{
	_RecordsetPtr rs;

	m_bIsRead = TRUE;
	try
	{
		CString strSql;
		strSql.Format(_T("select * from %s"),
			this->m_strRegularSetTableName);

		const _ConnectionPtr& pCon = GetRegularSetDB();
		rs = pCon->Execute(_bstr_t(strSql), NULL, adCmdText);
		if(rs == NULL)
		{
			return ;
		}
		while(!rs->adoEOF && !rs->BOF)
		{
			NewRegular(rs);
			rs->MoveNext();
		}
		rs->Close();
	}
	catch(_com_error e)
	{
		if(rs != NULL && rs->GetState() == adStateOpen)
			rs->Close();
		
		ErrorAlert(e);
		ASSERT(FALSE);
	}
}

void JointRegularSet::NewRegular(_RecordsetPtr& rs)
{
	GeneralJointRegular* pRegular = new GeneralJointRegular;
	if(pRegular == NULL)
	{
		ReportMemoryError();
		return ;
	}

	pRegular->FirstJointTypeID(vtoi(rs->GetCollect(_T("JPF_Matched"))));
	pRegular->NextJointTypeID(vtoi(rs->GetCollect(_T("JPF_Matching"))));
	pRegular->PrevMatrixRegular(vtos(rs->GetCollect(_T("Matched_UnFreeField"))));
	pRegular->NextMatrixRegular(vtos(rs->GetCollect(_T("Matching_UnFreeField"))));

	CString strKey;
	strKey.Format(_T("%d_%d"), pRegular->FirstJointTypeID(), pRegular->NextJointTypeID());

	this->Add(strKey, pRegular);
}

void JointRegularSet::GetJointAttach(Joint* pJoint)
{
	_RecordsetPtr rs;

/*	Part* pPrev = pJoint->GetPrev()->GetOwner();
	Part* pNext = pJoint->GetNext()->GetOwner();*/

/*	JointInfo info(pPrev);
	if(info.GetJointNum() == 2)
	{
		JointFunction* pFun = info.GetFirst();
		if(pFun == pJoint->GetPrev())
		{
			pFun = pJoint->GetNext();
		}
		ASSERT(pFun);
		if(pFun->HasJoint())
		{
			ASSERT(pFun->GetOtherSide());
			Part* pPrevPrev = pFun->GetOtherSide()->GetOwner();
			
			CString strSql;
			strSql.Format(_T("select * from [connect] where CNTB = '%s' and CNTE = '%s' and CNTN = '%s'"),
				GetID(pPrevPrev), GetID(pPrev), GetID(pNext));
			
			const _ConnectionPtr& pCon = GetRegularSetDB();
			rs = pCon->Execute(_bstr_t(strSql), NULL, adCmdText);
			if(rs == NULL)
			{
				return ;
			}
			if(!rs->adoEOF && !rs->BOF)
			{
				GetAttach(rs, pJoint);
				rs->Close();
				return;
			}
			rs->Close();
		}
	}*/
/*	CString strSql;
	strSql.Format(_T("Select * from [connect] where CNTB = '%s' and CNTE = '%s'"),
		GetID(pPrev), GetID(pNext));
	const _ConnectionPtr& pCon = GetRegularSetDB();
	rs = pCon->Execute(_bstr_t(strSql), NULL, adCmdText);
	if(rs == NULL)
	{
		return ;
	}
	if(!rs->adoEOF && !rs->BOF)
	{
		GetAttach(rs, pJoint);
		rs->Close();
		return;
	}
	rs->Close();*/
}

const CString& JointRegularSet::GetID(Part* pPart)
{
	ASSERT(pPart);
	PartSortPropertySet* pSet = KnownPartSet::Instance().GetPartSortPropertySet(pPart->GetStandard());
	ASSERT(pSet);
	return pSet->GetPartSortProperty(pPart->GetCustomID())->ID();
}

void JointRegularSet::GetAttach(_RecordsetPtr& rs, Joint* pJoint)
{
/*	Part* pPart = NULL;
	for(int i = 1; i <= 8; i++)
	{
		CString strTemp;
		strTemp.Format(_T("CNTBF%d"), i);
		strTemp = vtos(rs->GetCollect(_variant_t(strTemp)));
		if(strTemp.IsEmpty())
		{
			return ;
		}
		pPart = GetPartGenerator().Generate(strTemp,
			GetPersistentFacade().GetCurPartSet()->GetCurStandardOfPart(strTemp));
		ASSERT(pPart);
		pPart->SetAttach();
		pJoint->AddAttach(pPart);
	}*/
}